﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;

namespace LBSoft.Common.DotNetExt
{
    public static class ExtObject
    {


        public static string ToString2(this object source)
        {
            if (source == null || source == DBNull.Value)
            {
                return string.Empty;
            }
            return source.ToString();
        }

        #region 转换为int32
        /// <summary>
        /// 转换为Int32 转换失败返回0
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static Int32 ToInt32(this object source)
        {
            return source.ToInt32(0);
        }

        /// <summary>
        /// 转换为Int32 转换失败返回默认值
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public static Int32 ToInt32(this object source, int defaultValue)
        {
            if (source == null || source == DBNull.Value)
            {
                return defaultValue;
            }

            int value = 0;
            if (int.TryParse(source.ToString(), out value))
            {
                return value;
            }
            return defaultValue;
        }
        #endregion

        #region
        /// <summary>
        /// 转换为Int64 转换失败返回0
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static Int64 ToInt64(this object source)
        {
            return source.ToInt64(0);
        }
        /// <summary>
        /// 转换为Int32 转换失败返回默认值
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public static Int64 ToInt64(this object source, int defaultValue)
        {
            if (source == null || source == DBNull.Value)
            {
                return defaultValue;
            }

            long value = 0;
            if (long.TryParse(source.ToString(), out value))
            {
                return value;
            }
            return defaultValue;
        }
        #endregion

        #region 转换为Double
        /// <summary>
        /// 转换为Double 转换失败返回0
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static Double ToDouble(this object source)
        {
            return source.ToDouble(0);
        }

        /// <summary>
        /// 转换为Double 转换失败返回默认值
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public static Double ToDouble(this object source, double defaultValue)
        {
            if (source == null || source == DBNull.Value)
            {
                return defaultValue;
            }

            double value = 0;
            if (double.TryParse(source.ToString(), out value))
            {
                return value;
            }
            return defaultValue;
        }
        #endregion

        #region 转换为float

        /// <summary>
        /// 转换为float 转换失败返回默认值
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public static float ToFloat(this object source, float defaultValue)
        {
            if (source == null || source == DBNull.Value)
            {
                return defaultValue;
            }
            float value = 0F;
            if (float.TryParse(source.ToString(), out value))
            {
                return value;
            }
            return defaultValue;
        }

        #endregion

        #region 转换为Guid?
        /// <summary>
        /// 转换为Guid值，当字符串不是一个合法的Guid值的时候，返回指定的默认值
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static Guid? ToGuid(this object source, Guid? defaultValue)
        {
            if (source == null || source == DBNull.Value)
            {
                return defaultValue;
            }

            try
            {
                return new Guid(source.ToString()); ;
            }
            catch (System.Exception ex)
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 转换为Guid值，当字符串不是一个合法的Guid值的时候，返回null
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static Guid? ToGuid(this object source)
        {
            return source.ToGuid(null);
        }


        #endregion

        #region 转换为DateTime
        /// <summary>
        /// 转换为DateTime 转换失败返回默认值
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defaultValue">默认值</param>
        /// <returns></returns>
        public static DateTime ToDateTime(this object source, DateTime defaultValue)
        {
            if (source == null || source == DBNull.Value)
            {
                return defaultValue;
            }

            DateTime value = defaultValue;
            if (DateTime.TryParse(source.ToString(), out value))
            {
                return value;
            }
            return defaultValue;
        }

        /// <summary>
        /// 转换为DateTime 转换失败返回DateTime.MinValue
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(this object source)
        {
            return source.ToDateTime(DateTime.MinValue);
        }

        /// <summary>
        /// 按指定格式格式化日期
        /// </summary>
        /// <param name="source"></param>
        /// <param name="format">格式，例如"yyyy-MM-dd"</param>
        /// <returns>空值和异常都返回空</returns>
        public static string DateTimeParse(this object source, string format = "")
        {
            try
            {
                string result = "";
                if (source == null)
                    return result;
                if (string.IsNullOrEmpty(format))
                    result = DateTime.Parse(source.ToString()).ToString();
                else
                {
                    result = DateTime.Parse(source.ToString()).ToString(format);
                }
                return result;
            }
            catch (Exception)
            {
                return "";
            }
        }

        #endregion

        #region 转换为List<Dictionary<string,object>>
        /// <summary>
        /// 转换为List<Dictionary<string,object>> 转换失败返回null
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static List<Dictionary<string, object>> ToDictionaryList(this object source)
        {
            List<Dictionary<string, object>> list = null;
            if (source != null && source != DBNull.Value)
            {
                try
                {
                    list = (List<Dictionary<string, object>>)source;
                }
                catch (System.Exception ex)
                {
                    return null;
                }
            }
            return list;
        }
        #endregion

        #region 转换为List<string>
        /// <summary>
        /// 转换为List(string) 转换失败返回null
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static List<string> ToList(this object source)
        {
            List<string> list = null;
            if (source != null && source != DBNull.Value)
            {
                try
                {
                    list = (List<string>)source;
                }
                catch (System.Exception ex)
                {
                    return null;
                }
            }
            return list;
        }
        #endregion

        #region 深度克隆
        /// <summary>
        /// 深度克隆一个对象 对象必须可序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source">原目标</param>
        /// <returns></returns>
        public static T DeepClone<T>(this T source) where T : class
        {
            MemoryStream ms = new MemoryStream();
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, source);
            ms.Position = 0;
            return bf.Deserialize(ms) as T;
        }
        #endregion

        #region 根据字符串得到相应的属性的值
        /// <summary>
        /// 根据字符串得到相应的属性的值
        /// </summary>
        /// <param name="source"></param>
        /// <param name="propertyName">属性名称</param>
        /// <returns></returns>
        public static object GetPropertyValue(this object source, string propertyName)
        {
            Type type = source.GetType();
            foreach (PropertyInfo pty in type.GetProperties())
            {
                if (pty.Name.ToLower() == propertyName.ToLower())
                {
                    return pty.GetValue(source, BindingFlags.GetProperty, null, null, null);
                }
            }
            return null;
        }
        #endregion
    }
}
